
package edu.uhcl.csci4838.group3.view;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;

import edu.uhcl.csci4838.group3.R;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCourse;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCourseTimeOverride;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorCoursesForAgendaView;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorHoliday;
import edu.uhcl.csci4838.group3.database.BackpackEduDatabaseHelper.CursorTaskForAgendaView;
import edu.uhcl.csci4838.group3.database.info.Course;
import edu.uhcl.csci4838.group3.database.info.Task;
import edu.uhcl.csci4838.group3.date.DateConstants;
import edu.uhcl.csci4838.group3.view.help.HelpActivity;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.TableLayout.LayoutParams;

public class AgendaTabActivity extends Activity {
	
	// An Object to hold the Course meeting entry
	private static class CourseMeetingEntry implements Comparable {
		
		private String courseName;
		private long id;
		private int startTimeHour;
		private int startTimeMinute;
		private int endTimeHour;
		private int endTimeMinute;
		
		public long getId() {
			return this.id;
		}
		
		public void setId(long id) {
			this.id = id;
		}
		
		public String getCourseName() {
			return this.courseName;
		}
		
		public void setCourseName(String courseName) {
			this.courseName = courseName;
		}
		
		public int getStartTimeHour() {
			return this.startTimeHour;
		}
		
		public void setStartTimeHour(int startTimeHour) {
			this.startTimeHour = startTimeHour;
		}
		
		public int getStartTimeMinute() {
			return this.startTimeMinute;
		}
		
		public void setStartTimeMinute(int startTimeMinute) {
			this.startTimeMinute = startTimeMinute;
		}
		
		public int getEndTimeHour() {
			return this.endTimeHour;
		}
		
		public void setEndTimeHour(int endTimeHour) {
			this.endTimeHour = endTimeHour;
		}
		
		public int getEndTimeMinute() {
			return this.endTimeMinute;
		}
		
		public void setEndTimeMinute(int endTimeMinute) {
			this.endTimeMinute = endTimeMinute;
		}
		
		public int compareTo(Object o) {
			int hour = ((CourseMeetingEntry) o).getStartTimeHour();
			int minute = ((CourseMeetingEntry) o).getStartTimeMinute();
			
			if (this.getStartTimeHour() == hour) {
				return this.getStartTimeMinute()
						- minute;
			}
			return this.getStartTimeHour()
					- hour;
			
		}
	}
	
	// A checkbox that holds the task Id
	private static class CustomCheckBox extends CheckBox {
		private Long taskId;
		
		public CustomCheckBox(Context context) {
			super(context);
		}
		
		public void setTaskId(long taskId) {
			this.taskId = taskId;
		}
		
		public long getTaskId() {
			return this.taskId;
		}
	}
	
	// A TextView that holds either a task id or a course id
	private static class CustomTextView extends TextView {
		
		private Long id;
		
		public CustomTextView(Context context) {
			super(context);
		}
		
		public void setTheId(long taskId) {
			this.id = taskId;
		}
		
		public long getTheId() {
			return this.id;
		}
	}
	
	// Db
	private BackpackEduDatabaseHelper db;
	
	// Cursors
	private CursorTaskForAgendaView tasks;
	private CursorCoursesForAgendaView courses;
	private CursorHoliday holidays;
	private CursorCourseTimeOverride courseTimeOverrides;
	
	// Adapters
	private ArrayAdapter<CharSequence> adapter;
	
	// Layouts and Views
	private TableLayout tblTasks;
	private TableLayout tblCourses;
	private RadioGroup radioGroup;
	private RadioButton radioTasks;
	private RadioButton radioCourses;
	private Spinner spinner;
	
	// Views' Listeners
	private View.OnClickListener textViewOnClickListenerTask;
	private View.OnClickListener textViewOnClickListenerCourse;
	private View.OnClickListener radioButtonOnClickListener;
	private View.OnClickListener checkBoxOnClickListener;
	private OnItemSelectedListener spinnerOnItemSelectedListenser;
	
	// Colors and Formattings
	private int colorTaskOrCourseEntry;
	private int colorDayBar;
	private int colorTextViewShadowLayer;
	private int colorWeekBar;
	private int textViewWidth, pTvLeft, pTvTop, pTvRight, pTvBottom;
	private int pCbLeft, pCbTop, pCbRight, pCbBottom;
	private int deviceWidth;
	private int checkBoxChecked;
	private int checkBoxUnChecked;
	
	// Misc.
	private GregorianCalendar gCalTask;
	private GregorianCalendar gCalCourse;
	private GregorianCalendar gCalWeekTask;
	private GregorianCalendar gCalWeekCourse;
	private int taskYearToday, taskMonthToday, taskDayToday;
	private int courseYearToday, courseMonthToday, courseDayToday;
	private long millisecondsPerDay;
	private ArrayList<CourseMeetingEntry> meetingEntries;
	private ArrayList<ArrayList<Integer>> meetingDays;
	private ArrayList<Integer> overrides;
	private int currentTblTasksIndex;
	private int currentTblCoursesIndex;
	
	// onCreate
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		setContentView(R.layout.layout_agenda);
		
		// Get display's width
		Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
		deviceWidth = display.getWidth();
		
		// Initialize current time for tasks and courses
		gCalTask = new GregorianCalendar();
		gCalTask = new GregorianCalendar(gCalTask.get(Calendar.YEAR),
				gCalTask.get(Calendar.MONTH),
				gCalTask.get(Calendar.DAY_OF_MONTH));
		gCalWeekTask = new GregorianCalendar();
		
		gCalCourse = new GregorianCalendar();
		gCalCourse = new GregorianCalendar(gCalCourse.get(Calendar.YEAR),
				gCalCourse.get(Calendar.MONTH),
				gCalCourse.get(Calendar.DAY_OF_MONTH));
		gCalWeekCourse = new GregorianCalendar();
		
		// Reference the xml layout items
		tblTasks = (TableLayout) findViewById(R.id.tblAgendaTasks);
		tblCourses = (TableLayout) findViewById(R.id.tblAgendaCourses);
		radioGroup = (RadioGroup) findViewById(R.id.radioGroup1);
		radioTasks = (RadioButton) findViewById(R.id.radioTasks);
		radioCourses = (RadioButton) findViewById(R.id.radioCourses);
		spinner = (Spinner) findViewById(R.id.spinnerPeriod);
		adapter = ArrayAdapter.createFromResource(this,
				R.array.agendaViewCoursePeriod,
				android.R.layout.simple_spinner_item);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinner.setAdapter(adapter);
		checkBoxChecked = R.drawable.btn_check_on_pressed;
		checkBoxUnChecked = R.drawable.btn_check_off_pressed;
		
		millisecondsPerDay = Long.valueOf(24 * 60 * 60 * 1000);
		spinner.setSelection(1);
		
		// Open db connection
		db = new BackpackEduDatabaseHelper(this);
		
		// Initialize Listeners
		checkBoxOnClickListener = new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				CustomCheckBox ccb = (CustomCheckBox) arg0;
				ContentValues cVals = new ContentValues();
				
				if (ccb.isChecked()) {
					ccb.setButtonDrawable(checkBoxChecked);
					cVals.put(Task.IS_COMPLETED,
							1);
					db.editTask(ccb.getTaskId(),
							cVals);
				} else {
					ccb.setButtonDrawable(checkBoxUnChecked);
					cVals.put(Task.IS_COMPLETED,
							0);
					db.editTask(ccb.getTaskId(),
							cVals);
				}
			}
		};
		textViewOnClickListenerTask = new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				CustomTextView ctv = (CustomTextView) arg0;
				// Start task activity
				final Intent intent = new Intent(getApplicationContext(),
						TaskActivity.class);
				// Log.d("ctv.getTheId(): ", "" + ctv.getTheId());
				intent.putExtra(getString(R.string.intent_extra_taskId),
						ctv.getTheId());
				startActivity(intent);
			}
		};
		textViewOnClickListenerCourse = new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				CustomTextView ctv = (CustomTextView) arg0;
				// Start course activity
				final Intent intent = new Intent(getApplicationContext(),
						CourseInfoTabActivity.class);
				// Log.d("ctv.getTheId(): ",
				// ""
				// + ctv.getTheId());
				intent.putExtra(getString(R.string.intent_extra_courseId),
						ctv.getTheId());
				startActivity(intent);
			}
		};
		radioButtonOnClickListener = new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				int selectRadioButton = radioGroup.getCheckedRadioButtonId();
				if (selectRadioButton == R.id.radioTasks) {
					
					// Correct visibility
					tblCourses.setVisibility(View.GONE);
					spinner.setVisibility(View.GONE);
					tblTasks.setVisibility(View.VISIBLE);
					
					// Correct the time for task
					gCalTask = new GregorianCalendar();
					gCalTask = new GregorianCalendar(gCalTask.get(Calendar.YEAR),
							gCalTask.get(Calendar.MONTH),
							gCalTask.get(Calendar.DAY_OF_MONTH));
					
					// Check if this is a new day
					if (gCalTask.get(Calendar.DAY_OF_MONTH) != taskDayToday
							|| gCalTask.get(Calendar.MONTH) != taskMonthToday
							|| gCalTask.get(Calendar.YEAR) != taskYearToday) {
						
						// Get new cursor
						tasks.close();
						tasks = db.getTasksForAgendaView(gCalTask.getTimeInMillis());
						
						// Log.d("Date has changed!", "Date has changed!");
						
						fillTasks();
						
					} else if (isTaskCursorChanged()) {
						// Log.d("isTaskCursorChanged()",
						// "isTaskCursorChanged");
						
						// Get new cursor
						tasks.close();
						tasks = db.getTasksForAgendaView(gCalTask.getTimeInMillis());
						
						// Log.d("tasks.getCount() after reassigning",
						// "" + tasks.getCount());
						// Log.d("gCalTask.getTimeInMillis()",
						// "" + gCalTask.getTimeInMillis());
						
						fillTasks();
					}
					
				} else {
					
					// Correct visibility
					tblTasks.setVisibility(View.GONE);
					spinner.setVisibility(View.VISIBLE);
					tblCourses.setVisibility(View.VISIBLE);
					
					// Correct the time for course
					gCalCourse = new GregorianCalendar();
					gCalCourse = new GregorianCalendar(gCalCourse.get(Calendar.YEAR),
							gCalCourse.get(Calendar.MONTH),
							gCalCourse.get(Calendar.DAY_OF_MONTH));
					
					// Check if this is a new day
					if (gCalCourse.get(Calendar.DAY_OF_MONTH) != courseDayToday
							|| gCalCourse.get(Calendar.MONTH) != courseMonthToday
							|| gCalCourse.get(Calendar.YEAR) != courseYearToday) {
						
						// Get new cursor
						courses.close();
						courses = db.getCoursesForAgendaView(gCalCourse.getTimeInMillis(),
								getRightBound());
						
						holidays.close();
						holidays = db.getHolidaysForAgendaView(gCalCourse.getTimeInMillis(),
								getRightBound());
						
						courseTimeOverrides.close();
						courseTimeOverrides = db.getCourseTimeOverridesForAgendaView(gCalCourse.getTimeInMillis(),
								getRightBound());
						
						// Log.d("Date has changed!", "Date has changed!");
						
						fillCourses();
						
					} else if (isCourseCursorChanged()) {
						// Log.d("isCourseCursorChanged()",
						// "isCourseCursorChanged");
						
						// Get new cursor
						courses.close();
						courses = db.getCoursesForAgendaView(gCalCourse.getTimeInMillis(),
								getRightBound());
						
						holidays.close();
						holidays = db.getHolidaysForAgendaView(gCalCourse.getTimeInMillis(),
								getRightBound());
						
						courseTimeOverrides.close();
						courseTimeOverrides = db.getCourseTimeOverridesForAgendaView(gCalCourse.getTimeInMillis(),
								getRightBound());
						
						fillCourses();
					}
				}
			}
		};
		spinnerOnItemSelectedListenser = new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0,
					View arg1,
					int arg2,
					long arg3) {
				
				// Re-click the selected radio button
				int selectRadioButton = radioGroup.getCheckedRadioButtonId();
				if (selectRadioButton == R.id.radioTasks) {
					radioTasks.performClick();
				} else {
					radioCourses.performClick();
				}
			}
			
			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// Empty
			}
		};
		
		// Register Listeners
		radioTasks.setOnClickListener(radioButtonOnClickListener);
		radioCourses.setOnClickListener(radioButtonOnClickListener);
		spinner.setOnItemSelectedListener(spinnerOnItemSelectedListenser);
		
		// Header views for Tasks table
		colorTaskOrCourseEntry = Color.parseColor("#00B259");
		colorDayBar = Color.parseColor("#FDB913");
		colorTextViewShadowLayer = Color.parseColor("#0078AE");
		colorWeekBar = Color.parseColor("#49AED0");
		CustomCheckBox ccb = new CustomCheckBox(this);
		CustomTextView ctv = new CustomTextView(this);
		TableRow tr;
		View v = new View(this);
		v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
				2));
		v.setBackgroundColor(Color.WHITE);
		;
		textViewWidth = deviceWidth
				- ccb.getWidth()
				- ccb.getPaddingLeft()
				- ccb.getPaddingRight();
		pTvLeft = ctv.getPaddingLeft();
		pTvTop = ctv.getPaddingTop() + 5;
		pTvRight = ctv.getPaddingRight();
		pTvBottom = ctv.getPaddingBottom() + 5;
		pCbLeft = ccb.getPaddingLeft() + 10;
		pCbTop = ccb.getPaddingTop();
		pCbRight = ccb.getPaddingRight();
		pCbBottom = ccb.getPaddingBottom();
		ccb.setButtonDrawable(checkBoxUnChecked);
		ccb.setPadding(pCbLeft,
				pCbTop,
				pCbRight,
				pCbBottom);
		TextView tv = new TextView(this);
		tv.setTextColor(Color.WHITE);
		tv.setText("There are no uncompleted tasks to show");
		
		// Add header views to Tasks table
		tblTasks.addView(tv);
		tblTasks.addView(v);
		
		// Header views for Courses table
		ctv = new CustomTextView(this);
		v = new View(this);
		v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
				2));
		v.setBackgroundColor(Color.WHITE);
		tv = new TextView(this);
		tv.setTextColor(Color.WHITE);
		tv.setText("There are no upcoming courses to show");
		
		// Add header views to Courses table
		tblCourses.addView(tv);
		tblCourses.addView(v);
		
		// Query the db
		tasks = db.getTasksForAgendaView(gCalTask.getTimeInMillis());
		
		courses = db.getCoursesForAgendaView(gCalCourse.getTimeInMillis(),
				getRightBound());
		
		holidays = db.getHolidaysForAgendaView(gCalCourse.getTimeInMillis(),
				getRightBound());
		
		courseTimeOverrides = db.getCourseTimeOverridesForAgendaView(gCalCourse.getTimeInMillis(),
				getRightBound());
		
		// Populate empty views for Tasks table
		for (int i = 0; i < tasks.getCount(); i++) {
			
			// Initializing
			ccb = new CustomCheckBox(this);
			ctv = new CustomTextView(this);
			tr = new TableRow(this);
			
			// Formatting
			ccb.setButtonDrawable(checkBoxUnChecked);
			ccb.setPadding(pCbLeft,
					pCbTop,
					pCbRight,
					pCbBottom);
			ccb.setOnClickListener(this.checkBoxOnClickListener);
			ctv.setWidth(textViewWidth);
			ctv.setPadding(pTvLeft,
					pTvTop,
					pTvRight,
					pTvBottom);
			ctv.setTextColor(Color.WHITE);
			ctv.setShadowLayer(4,
					3,
					3,
					colorTextViewShadowLayer);
			ctv.setTypeface(null,
					1);
			ctv.setOnClickListener(textViewOnClickListenerTask);
			tr.setGravity(Gravity.CENTER_VERTICAL);
			tr.setBackgroundColor(colorTaskOrCourseEntry);
			tr.setLayoutParams(new TableRow.LayoutParams(deviceWidth,
					android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
			v = new View(this);
			v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
					2));
			v.setBackgroundColor(Color.WHITE);
			
			// Adding views to table
			tr.addView(ccb);
			tr.addView(ctv);
			tblTasks.addView(tr);
			tblTasks.addView(v);
		}
		
		fillTasks();
		fillCourses();
		
	}
	
	// onResume()
	@Override
	protected void onResume() {
		super.onResume();
		
		// Auto click the selected radio button
		int selectRadioButton = radioGroup.getCheckedRadioButtonId();
		if (selectRadioButton == R.id.radioTasks) {
			radioTasks.performClick();
		} else {
			radioCourses.performClick();
		}
		
	}
	
	@Override
	protected void onDestroy() {
		db.close();
		tasks.close();
		courses.close();
		holidays.close();
		courseTimeOverrides.close();
		super.onDestroy();
	}
	
	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		this.getMenuInflater()
				.inflate(R.menu.options_agenda,
						menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		switch (item.getItemId()) {
			case R.id.menu_item_settings:
				this.startActivity(new Intent(this.getApplicationContext(),
						SettingsActivity.class));
				return true;
			case R.id.menu_item_about:
				this.startActivity(new Intent(this.getApplicationContext(),
						AboutActivity.class));
				return true;
			case R.id.menu_item_help:
				this.startActivity(new Intent(this.getApplicationContext(),
						HelpActivity.class));
				return true;
			default:
				Log.wtf("BackpackEDU",
						"Undefined options menu item.");
				return super.onOptionsItemSelected(item);
		}
	}
	
	// addNewDayBar()
	private void addNewDayBar(String dayOfWeek,
			boolean isTask,
			boolean isSaved) {
		
		CustomCheckBox ccb;
		CustomTextView ctv;
		View v;
		TableRow tr;
		
		if (isTask) {
			
			// Add a new week bar if needed
			if (isSaved
					|| gCalTask.getTimeInMillis() >= gCalWeekTask.getTimeInMillis()) {
				addNewWeekBar(true);
			}
			
			if (!(currentTblTasksIndex < tblTasks.getChildCount())) {
				
				// Initializing views
				ccb = new CustomCheckBox(this);
				ctv = new CustomTextView(this);
				tr = new TableRow(this);
				v = new View(this);
				
				// Formatting
				v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
						2));
				v.setBackgroundColor(Color.WHITE);
				tr.setLayoutParams(new TableRow.LayoutParams((android.view.ViewGroup.LayoutParams.MATCH_PARENT),
						android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
				ccb.setButtonDrawable(checkBoxUnChecked);
				ccb.setPadding(pCbLeft,
						pCbTop,
						pCbRight,
						pCbBottom);
				ccb.setVisibility(View.GONE);
				ctv.setWidth(deviceWidth);
				ctv.setPadding(pTvLeft,
						pTvTop - 5,
						pTvRight,
						pTvBottom - 5);
				ctv.setTextColor(Color.WHITE);
				ctv.setShadowLayer(4,
						3,
						3,
						colorTextViewShadowLayer);
				ctv.setTypeface(null,
						1);
				ctv.setGravity(Gravity.CENTER);
				ctv.setBackgroundColor(colorDayBar);
				String month = switchMonth(gCalTask.get(Calendar.MONTH));
				int tempDay = gCalTask.get(Calendar.DAY_OF_MONTH);
				String dayOfMonth = tempDay < 10
						? "0"
								+ tempDay
						: ""
								+ tempDay;
				
				if (isSaved) {
					ctv.setText(dayOfWeek
							+ " - "
							+ switchDayOfWeek(gCalTask.get(Calendar.DAY_OF_WEEK))
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				} else {
					ctv.setText(dayOfWeek
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				}
				
				tr.setGravity(Gravity.CENTER_VERTICAL);
				tr.setBackgroundColor(colorTaskOrCourseEntry);
				
				// Adding views to table
				tr.addView(ccb);
				tr.addView(ctv);
				tblTasks.addView(tr);
				tblTasks.addView(v);
				
			} else {
				
				// Getting views
				tr = (TableRow) tblTasks.getChildAt(currentTblTasksIndex);
				ccb = (CustomCheckBox) tr.getChildAt(0);
				ctv = (CustomTextView) tr.getChildAt(1);
				v = tblTasks.getChildAt(currentTblTasksIndex + 1);
				
				// Formating
				v.setVisibility(View.VISIBLE);
				ccb.setVisibility(View.GONE);
				ctv.setGravity(Gravity.CENTER);
				ctv.setBackgroundColor(colorDayBar);
				ctv.setWidth(deviceWidth);
				ctv.setPadding(pTvLeft,
						pTvTop - 5,
						pTvRight,
						pTvBottom - 5);
				ctv.setShadowLayer(4,
						3,
						3,
						colorTextViewShadowLayer);
				ctv.setTypeface(null,
						1);
				ctv.setTextColor(Color.WHITE);
				ctv.setClickable(false);
				String month = switchMonth(gCalTask.get(Calendar.MONTH));
				int tempDay = gCalTask.get(Calendar.DAY_OF_MONTH);
				String dayOfMonth = tempDay < 10
						? "0"
								+ tempDay
						: ""
								+ tempDay;
				
				if (isSaved) {
					ctv.setText(dayOfWeek
							+ " - "
							+ switchDayOfWeek(gCalTask.get(Calendar.DAY_OF_WEEK))
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				} else {
					ctv.setText(dayOfWeek
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				}
				
				// Change views visibility
				tr.setVisibility(View.VISIBLE);
				
			}
			
			// Move the view index to the next position
			currentTblTasksIndex += 2;
			
			// Save today
			if (isSaved) {
				taskDayToday = gCalTask.get(Calendar.DAY_OF_MONTH);
				taskMonthToday = gCalTask.get(Calendar.MONTH);
				taskYearToday = gCalTask.get(Calendar.YEAR);
			}
			
		} else {
			
			// Add a new week bar if needed
			if (isSaved
					|| gCalCourse.getTimeInMillis() >= gCalWeekCourse.getTimeInMillis()) {
				addNewWeekBar(false);
			}
			
			if (!(currentTblCoursesIndex < tblCourses.getChildCount())) {
				
				// Initializing views
				ctv = new CustomTextView(this);
				v = new View(this);
				
				// Formatting
				v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
						2));
				v.setBackgroundColor(Color.WHITE);
				ctv.setWidth(deviceWidth);
				ctv.setPadding(pTvLeft,
						pTvTop - 5,
						pTvRight,
						pTvBottom - 5);
				ctv.setTextColor(Color.WHITE);
				ctv.setShadowLayer(4,
						3,
						3,
						colorTextViewShadowLayer);
				ctv.setTypeface(null,
						1);
				ctv.setGravity(Gravity.CENTER);
				ctv.setBackgroundColor(colorDayBar);
				String month = switchMonth(gCalCourse.get(Calendar.MONTH));
				int tempDay = gCalCourse.get(Calendar.DAY_OF_MONTH);
				String dayOfMonth = tempDay < 10
						? "0"
								+ tempDay
						: ""
								+ tempDay;
				
				if (isSaved) {
					ctv.setText(dayOfWeek
							+ " - "
							+ switchDayOfWeek(gCalCourse.get(Calendar.DAY_OF_WEEK))
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				} else {
					ctv.setText(dayOfWeek
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				}
				
				// Adding views to table
				tblCourses.addView(ctv);
				tblCourses.addView(v);
				
			} else {
				
				// Getting views
				ctv = (CustomTextView) tblCourses.getChildAt(currentTblCoursesIndex);
				v = tblCourses.getChildAt(currentTblCoursesIndex + 1);
				
				// Formating
				ctv.setGravity(Gravity.CENTER);
				ctv.setBackgroundColor(colorDayBar);
				ctv.setWidth(deviceWidth);
				ctv.setPadding(pTvLeft,
						pTvTop - 5,
						pTvRight,
						pTvBottom - 5);
				ctv.setShadowLayer(4,
						3,
						3,
						colorTextViewShadowLayer);
				ctv.setTypeface(null,
						1);
				ctv.setTextColor(Color.WHITE);
				ctv.setClickable(false);
				String month = switchMonth(gCalCourse.get(Calendar.MONTH));
				int tempDay = gCalCourse.get(Calendar.DAY_OF_MONTH);
				String dayOfMonth = tempDay < 10
						? "0"
								+ tempDay
						: ""
								+ tempDay;
				
				if (isSaved) {
					ctv.setText(dayOfWeek
							+ " - "
							+ switchDayOfWeek(gCalCourse.get(Calendar.DAY_OF_WEEK))
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				} else {
					ctv.setText(dayOfWeek
							+ ", "
							+ month
							+ " "
							+ dayOfMonth);
				}
				
				// Change views visibility
				v.setVisibility(View.VISIBLE);
				ctv.setVisibility(View.VISIBLE);
				
			}
			
			// Move the view index to the next position
			currentTblCoursesIndex += 2;
			
			// Save today
			if (isSaved) {
				courseDayToday = gCalCourse.get(Calendar.DAY_OF_MONTH);
				courseMonthToday = gCalCourse.get(Calendar.MONTH);
				courseYearToday = gCalCourse.get(Calendar.YEAR);
			}
			
		}
	}
	
	private void addNewWeekBar(boolean isTask) {
		
		CustomCheckBox ccb;
		CustomTextView ctv;
		View v;
		TableRow tr;
		
		if (!isTask) {
			
			// Check to see if the day is monday
			GregorianCalendar tempCal = new GregorianCalendar(gCalCourse.get(Calendar.YEAR),
					gCalCourse.get(Calendar.MONTH),
					gCalCourse.get(Calendar.DAY_OF_MONTH));
			
			if (tempCal.get(Calendar.DAY_OF_WEEK) != 2) {
				if (tempCal.get(Calendar.DAY_OF_WEEK) == 1) {
					tempCal.set(Calendar.DAY_OF_MONTH,
							tempCal.get(Calendar.DAY_OF_MONTH) - 6);
				} else {
					tempCal.set(Calendar.DAY_OF_MONTH,
							tempCal.get(Calendar.DAY_OF_MONTH)
									- (tempCal.get(Calendar.DAY_OF_WEEK) - 2));
				}
			}
			
			gCalWeekCourse.setTimeInMillis(tempCal.getTimeInMillis());
			gCalWeekCourse.set(Calendar.DAY_OF_MONTH,
					gCalWeekCourse.get(Calendar.DAY_OF_MONTH) + 7);
			
			if (!(currentTblCoursesIndex < tblCourses.getChildCount())) {
				
				// Initializing views
				ctv = new CustomTextView(this);
				v = new View(this);
				v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
						2));
				v.setBackgroundColor(Color.WHITE);
				
				// Adding views to table
				tblCourses.addView(ctv);
				tblCourses.addView(v);
				
			} else {
				
				// Getting views
				ctv = (CustomTextView) tblCourses.getChildAt(currentTblCoursesIndex);
				v = tblCourses.getChildAt(currentTblCoursesIndex + 1);
				
				// Change views visibility
				v.setVisibility(View.VISIBLE);
				ctv.setVisibility(View.VISIBLE);
				
			}
			
			// Formating
			ctv.setGravity(Gravity.CENTER);
			ctv.setBackgroundColor(colorWeekBar);
			ctv.setWidth(deviceWidth);
			ctv.setPadding(pTvLeft,
					pTvTop,
					pTvRight,
					pTvBottom);
			ctv.setShadowLayer(4,
					3,
					3,
					colorTextViewShadowLayer);
			ctv.setTypeface(null,
					1);
			ctv.setTextColor(Color.WHITE);
			ctv.setClickable(false);
			String month = switchMonth(tempCal.get(Calendar.MONTH));
			int tempDay = tempCal.get(Calendar.DAY_OF_MONTH);
			String dayOfMonth = tempDay < 10
					? "0"
							+ tempDay
					: ""
							+ tempDay;
			ctv.setText(Html.fromHtml("<big>"
					+ "Week of "
					+ month
					+ " "
					+ dayOfMonth
					+ "</big>"));
			
			// Move the view index to the next position
			currentTblCoursesIndex += 2;
			
		}
		
		else {
			
			// Check to see if the day is monday
			GregorianCalendar tempCal = new GregorianCalendar(gCalTask.get(Calendar.YEAR),
					gCalTask.get(Calendar.MONTH),
					gCalTask.get(Calendar.DAY_OF_MONTH));
			
			if (tempCal.get(Calendar.DAY_OF_WEEK) != 2) {
				if (tempCal.get(Calendar.DAY_OF_WEEK) == 1) {
					tempCal.set(Calendar.DAY_OF_MONTH,
							tempCal.get(Calendar.DAY_OF_MONTH) - 6);
				} else {
					tempCal.set(Calendar.DAY_OF_MONTH,
							tempCal.get(Calendar.DAY_OF_MONTH)
									- (tempCal.get(Calendar.DAY_OF_WEEK) - 2));
				}
			}
			
			gCalWeekTask.setTimeInMillis(tempCal.getTimeInMillis());
			gCalWeekTask.set(Calendar.DAY_OF_MONTH,
					gCalWeekTask.get(Calendar.DAY_OF_MONTH) + 7);
			
			if (!(currentTblTasksIndex < tblTasks.getChildCount())) {
				
				// Initializing views
				ccb = new CustomCheckBox(this);
				ctv = new CustomTextView(this);
				tr = new TableRow(this);
				v = new View(this);
				
				// Formatting
				v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
						2));
				v.setBackgroundColor(Color.WHITE);
				tr.setLayoutParams(new TableRow.LayoutParams((android.view.ViewGroup.LayoutParams.MATCH_PARENT),
						android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
				ccb.setButtonDrawable(checkBoxUnChecked);
				ccb.setPadding(pCbLeft,
						pCbTop,
						pCbRight,
						pCbBottom);
				ccb.setVisibility(View.GONE);
				tr.setGravity(Gravity.CENTER_VERTICAL);
				tr.setBackgroundColor(colorTaskOrCourseEntry);
				
				// Adding views to table
				tr.addView(ccb);
				tr.addView(ctv);
				tblTasks.addView(tr);
				tblTasks.addView(v);
				
			} else {
				
				// Getting views
				tr = (TableRow) tblTasks.getChildAt(currentTblTasksIndex);
				ccb = (CustomCheckBox) tr.getChildAt(0);
				ctv = (CustomTextView) tr.getChildAt(1);
				v = tblTasks.getChildAt(currentTblTasksIndex + 1);
				
				// Formating
				v.setVisibility(View.VISIBLE);
				ccb.setVisibility(View.GONE);
				
				// Change views visibility
				tr.setVisibility(View.VISIBLE);
				
			}
			
			// Formating
			ctv.setGravity(Gravity.CENTER);
			ctv.setBackgroundColor(colorWeekBar);
			ctv.setWidth(deviceWidth);
			ctv.setPadding(pTvLeft,
					pTvTop,
					pTvRight,
					pTvBottom);
			ctv.setShadowLayer(4,
					3,
					3,
					colorTextViewShadowLayer);
			ctv.setTypeface(null,
					1);
			ctv.setTextColor(Color.WHITE);
			ctv.setClickable(false);
			String month = switchMonth(tempCal.get(Calendar.MONTH));
			int tempDay = tempCal.get(Calendar.DAY_OF_MONTH);
			String dayOfMonth = tempDay < 10
					? "0"
							+ tempDay
					: ""
							+ tempDay;
			ctv.setText(Html.fromHtml("<big>"
					+ "Week of "
					+ month
					+ " "
					+ dayOfMonth
					+ "</big>"));
			
			// Move the view index to the next position
			currentTblTasksIndex += 2;
			
		}
		
	}
	
	// addNewTask()
	private void addNewTask(boolean isNoTaskDueToday) {
		
		// Vars
		String month = "";
		String dayOfWeek = "";
		String dayOfMonth = "";
		String tempString;
		int tempDay;
		CustomCheckBox ccb;
		CustomTextView ctv;
		View v;
		TableRow tr;
		GregorianCalendar dateDue = new GregorianCalendar();
		dateDue.setTimeInMillis(tasks.getColDateDue());
		
		if (!(currentTblTasksIndex < tblTasks.getChildCount())) {
			
			// Initializing
			ccb = new CustomCheckBox(this);
			ctv = new CustomTextView(this);
			tr = new TableRow(this);
			v = new View(this);
			
			// Formatting
			if (isNoTaskDueToday) {
				formatViewsForNewTask(null,
						ccb,
						ctv,
						tr);
			} else {
				formatViewsForNewTask(dateDue,
						ccb,
						ctv,
						tr);
			}
			v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
					2));
			v.setBackgroundColor(Color.WHITE);
			ctv.setOnClickListener(textViewOnClickListenerTask);
			
			// Adding views to table
			tr.addView(ccb);
			tr.addView(ctv);
			tblTasks.addView(tr);
			tblTasks.addView(v);
			
		} else {
			
			// Initializing
			tr = (TableRow) tblTasks.getChildAt(currentTblTasksIndex);
			ccb = (CustomCheckBox) tr.getChildAt(0);
			ctv = (CustomTextView) tr.getChildAt(1);
			v = tblTasks.getChildAt(currentTblTasksIndex + 1);
			
			// Formatting
			v.setVisibility(View.VISIBLE);
			if (isNoTaskDueToday) {
				formatViewsForNewTask(null,
						ccb,
						ctv,
						tr);
			} else {
				formatViewsForNewTask(dateDue,
						ccb,
						ctv,
						tr);
			}
			
			// Change table row visibility
			tr.setVisibility(View.VISIBLE);
		}
		
		// Move the view index to the next position
		currentTblTasksIndex += 2;
		
	}
	
	// addCourseEntry()
	private void addCourseEntry(boolean isTodayNoCourseMeeting,
			boolean isHoliday,
			CourseMeetingEntry entry) {
		
		CustomTextView ctv;
		View v;
		
		if (currentTblCoursesIndex < tblCourses.getChildCount()) {
			
			ctv = (CustomTextView) tblCourses.getChildAt(currentTblCoursesIndex);
			ctv.setVisibility(View.VISIBLE);
			ctv.setPadding(pTvLeft + 5,
					pTvTop,
					pTvRight,
					pTvBottom);
			v = tblCourses.getChildAt(currentTblCoursesIndex + 1);
			v.setVisibility(View.VISIBLE);
			
		} else {
			
			ctv = new CustomTextView(this);
			ctv.setOnClickListener(textViewOnClickListenerCourse);
			ctv.setWidth(deviceWidth);
			v = new View(this);
			v.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
					2));
			v.setBackgroundColor(Color.WHITE);
			tblCourses.addView(ctv);
			tblCourses.addView(v);
			
		}
		
		if (isTodayNoCourseMeeting) {
			
			// fill data to the custom textview
			ctv.setText("There are no course meetings today");
			
			// Formatting the view
			ctv.setPadding(pTvLeft,
					pTvTop + 3,
					pTvRight,
					pTvBottom + 3);
			ctv.setGravity(Gravity.CENTER_HORIZONTAL);
			ctv.setClickable(false);
			
		} else {
			
			if (isHoliday) {
				
				ctv.setTheId(courses.getColId());
				ctv.setText(Html.fromHtml("&nbsp;&nbsp;"
						+ courses.getColName()
						+ "<br />&nbsp;&nbsp;<small>"
						+ holidays.getColName()
						+ "</small>"));
				
			} else {
				
				String tempString = (entry.getStartTimeHour() > 12
						? ""
								+ (entry.getStartTimeHour() - 12)
						: ""
								+ entry.getStartTimeHour())
						+ ":"
						+ (entry.getStartTimeMinute() < 10
								? "0"
										+ entry.getStartTimeMinute()
								: entry.getStartTimeMinute())
						+ (entry.getStartTimeHour() > 12
								? " PM"
								: " AM")
						+ " - "
						+ (entry.getEndTimeHour() > 12
								? ""
										+ (entry.getEndTimeHour() - 12)
								: ""
										+ entry.getEndTimeHour())
						+ ":"
						+ (entry.getEndTimeMinute() < 10
								? "0"
										+ entry.getEndTimeMinute()
								: entry.getEndTimeMinute())
						+ (entry.getEndTimeHour() > 12
								? " PM"
								: " AM");
				
				ctv.setText(Html.fromHtml("&nbsp;&nbsp;"
						+ entry.getCourseName()
						+ "<br />&nbsp;&nbsp;<small>"
						+ tempString
						+ "</small>"));
				ctv.setTheId(entry.getId());
			}
			
			// Formatting the view
			ctv.setClickable(true);
			ctv.setGravity(Gravity.LEFT);
			ctv.setPadding(pTvLeft,
					pTvTop,
					pTvRight,
					pTvBottom);
			
		}
		
		// Formatting common format
		ctv.setBackgroundColor(colorTaskOrCourseEntry);
		ctv.setTextColor(Color.WHITE);
		ctv.setShadowLayer(4,
				3,
				3,
				colorTextViewShadowLayer);
		ctv.setTypeface(null,
				1);
		
		// Move the view index to the next position
		currentTblCoursesIndex += 2;
		
	}
	
	// formatViewsForNewTask()
	private void formatViewsForNewTask(GregorianCalendar dateDue,
			CustomCheckBox ccb,
			CustomTextView ctv,
			TableRow tr) {
		
		String tempString = "";
		
		ccb.setButtonDrawable(checkBoxUnChecked);
		ccb.setPadding(pCbLeft,
				pCbTop,
				pCbRight,
				pCbBottom);
		ccb.setTaskId(tasks.getColId());
		ccb.setOnClickListener(this.checkBoxOnClickListener);
		
		ctv.setPadding(pTvLeft,
				pTvTop,
				pTvRight,
				pTvBottom);
		ctv.setTextColor(Color.WHITE);
		ctv.setShadowLayer(4,
				3,
				3,
				colorTextViewShadowLayer);
		ctv.setTypeface(null,
				1);
		if (dateDue != null) {
			
			ccb.setVisibility(View.VISIBLE);
			ccb.setChecked(false);
			tempString += dateDue.get(Calendar.HOUR_OF_DAY) > 12
					? dateDue.get(Calendar.HOUR_OF_DAY) - 12
					: dateDue.get(Calendar.HOUR_OF_DAY);
			tempString += ":"
					+ (dateDue.get(Calendar.MINUTE) < 10
							? "0"
									+ dateDue.get(Calendar.MINUTE)
							: dateDue.get(Calendar.MINUTE));
			tempString += (dateDue.get(Calendar.AM_PM) == 0
					? " AM"
					: " PM");
			tempString += " - "
					+ tasks.getColCourseName();
			ctv.setWidth(textViewWidth);
			ctv.setGravity(Gravity.LEFT);
			ctv.setPadding(pTvLeft,
					pTvTop,
					pTvRight,
					pTvBottom);
			ctv.setText(Html.fromHtml(tasks.getColName()
					+ "<br /><small>"
					+ tempString
					+ "</small>"));
			ctv.setBackgroundColor(colorTaskOrCourseEntry);
			ctv.setClickable(true);
			ctv.setTheId(tasks.getColId());
		} else {
			ccb.setVisibility(View.GONE);
			ctv.setWidth(deviceWidth);
			ctv.setPadding(pTvLeft,
					pTvTop + 3,
					pTvRight,
					pTvBottom + 3);
			ctv.setGravity(Gravity.CENTER_HORIZONTAL);
			ctv.setText("There are no uncompleted tasks for today");
			ctv.setClickable(false);
			ctv.setBackgroundColor(colorTaskOrCourseEntry);
		}
		
		tr.setLayoutParams(new TableRow.LayoutParams((android.view.ViewGroup.LayoutParams.MATCH_PARENT),
				android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
		tr.setGravity(Gravity.CENTER_VERTICAL);
		tr.setBackgroundColor(colorTaskOrCourseEntry);
	}
	
	// fillTask()
	private void fillTasks() {
		
		currentTblTasksIndex = 2;
		
		// Vars
		long nextDay = gCalTask.getTimeInMillis()
				+ millisecondsPerDay;
		int i;
		
		//
		
		// Start adding all tasks in cursor
		
		if (tasks.getCount() < 1) {
			((TextView) tblTasks.getChildAt(0)).setVisibility(View.VISIBLE);
			currentTblTasksIndex = 1;
		} else {
			
			((TextView) tblTasks.getChildAt(0)).setVisibility(View.GONE);
			((View) tblTasks.getChildAt(1)).setVisibility(View.VISIBLE);
			
			// Add the today bar
			addNewDayBar("Today",
					true,
					true);
			
			// Add all the tasks for today
			for (i = 0; i < tasks.getCount(); i++) {
				
				// Move the cursor forward
				tasks.moveToPosition(i);
				
				// Add the task to the current day
				if (!(tasks.getColDateDue() < nextDay)) {
					break;
				} else {
					addNewTask(false);
				}
			}
			
			// if there are no tasks for today
			if (tasks.getPosition() == 0) {
				addNewTask(true);
			}
			
			// Add all tasks not due today
			for (; i < tasks.getCount(); i++) {
				
				// Move the cursor forward
				tasks.moveToPosition(i);
				
				// Add a new day bar if needed
				if (!(tasks.getColDateDue() < nextDay)) {
					// Move the time to the next task
					gCalTask.setTimeInMillis(tasks.getColDateDue());
					gCalTask.set(gCalTask.get(Calendar.YEAR),
							gCalTask.get(Calendar.MONTH),
							gCalTask.get(Calendar.DAY_OF_MONTH));
					nextDay = gCalTask.getTimeInMillis()
							+ millisecondsPerDay;
					addNewDayBar(switchDayOfWeek(gCalTask.get(Calendar.DAY_OF_WEEK)),
							true,
							false);
				}
				
				// Add the task to the current day
				addNewTask(false);
			}
		}
		
		// Hide all extra rows
		for (i = currentTblTasksIndex; i < tblTasks.getChildCount(); i++) {
			tblTasks.getChildAt(i)
					.setVisibility(View.GONE);
		}
		
		// Redraw the screen
		tblTasks.invalidate();
	}
	
	// fillCourses()
	private void fillCourses() {
		
		currentTblCoursesIndex = 2;
		
		if (courses.getCount() < 1
				&& courseTimeOverrides.getCount() < 1) {
			
			// Unhide the empty text view
			((TextView) tblCourses.getChildAt(0)).setVisibility(View.VISIBLE);
			currentTblCoursesIndex = 1;
			
		} else {
			
			// Hide the empty text view
			((TextView) tblCourses.getChildAt(0)).setVisibility(View.GONE);
			((View) tblCourses.getChildAt(1)).setVisibility(View.VISIBLE);
			
			// Initialize all the course time overrides to not taken
			unsetCourseTimeOverrides();
			
			// Get all the meeting days from dayBitFields
			setMeetingDays();
			
			// Vars
			long nextDay = gCalCourse.getTimeInMillis()
					+ millisecondsPerDay;
			long rightBound = getRightBound();
			boolean isOverride, isHoliday;
			CourseMeetingEntry entry;
			
			// Add the today bar
			addNewDayBar("Today",
					false,
					true);
			
			// Add all the course entries today to the batch
			for (boolean isToday = true, isAddDayBar = false; gCalCourse.getTimeInMillis() < rightBound; gCalCourse.setTimeInMillis(gCalCourse.getTimeInMillis()
					+ millisecondsPerDay), nextDay += millisecondsPerDay, isToday = false, isAddDayBar = true) {
				
				// Initialize the batch
				meetingEntries = new ArrayList<AgendaTabActivity.CourseMeetingEntry>();
				
				// Go through all the courses in the cursor
				for (int i = 0; i < courses.getCount(); i++) {
					
					// Move the course cursor to the correct position
					courses.moveToPosition(i);
					
					// Check to see if today is in the course meeting period
					if (gCalCourse.getTimeInMillis() >= courses.getColStartDate()
							&& gCalCourse.getTimeInMillis() < courses.getColEndDate()) {
						
						// Unset isHoliday and isOverride
						isHoliday = isOverride = false;
						
						// Check to see if the course meets today
						if (meetingDays.get(i)
								.contains(gCalCourse.get(Calendar.DAY_OF_WEEK))) {
							
							// Add a new day bar if needed
							if (isAddDayBar) {
								addNewDayBar(switchDayOfWeek(gCalCourse.get(Calendar.DAY_OF_WEEK)),
										false,
										false);
							}
							
							// Unset the add day bar
							isAddDayBar = false;
							isToday = false;
							
							// Initialize the entry
							entry = new CourseMeetingEntry();
							
							// Get all the overrides for today
							for (int j = 0; j < courseTimeOverrides.getCount(); j++) {
								
								// Move the cursor to the correct position
								courseTimeOverrides.moveToPosition(j);
								
								// Add an entry if there is an override
								if (overrides.contains(0)) {
									if (courses.getColId() == courseTimeOverrides.getColCourseId()
											&& overrides.get(j) == 0
											&& courseTimeOverrides.getColDate() >= gCalCourse.getTimeInMillis()
											&& courseTimeOverrides.getColDate() < nextDay) {
										
										// Set the isOverride flag
										isOverride = true;
										
										// Initializing the entry
										entry.setCourseName(courseTimeOverrides.getColCourseName());
										entry.setId(courseTimeOverrides.getColCourseId());
										entry.setStartTimeHour(courseTimeOverrides.getColStartTimeHour());
										entry.setStartTimeMinute(courseTimeOverrides.getColStartTimeMinute());
										entry.setEndTimeHour(courseTimeOverrides.getColEndTimeHour());
										entry.setEndTimeMinute(courseTimeOverrides.getColEndTimeMinute());
										
										// Add the entry to the batch
										meetingEntries.add(entry);
										
										// Unset the position in the override
										// array list
										overrides.set(j,
												1);
									}
								}
							} // end getting all overrides for today
							
							if (!(isOverride)) {
								// Check to see if today is within the holiday
								// period defined for the semester the course
								// belongs to
								
								for (int k = 0; k < holidays.getCount(); k++) {
									
									// Move the cursor to the correct
									// position
									holidays.moveToPosition(k);
									
									// Log.d("courses.getColSemesterId() + \" - \" + holidays.getColSemesterId()",
									// ""
									// + courses.getColSemesterId()
									// + " - "
									// + holidays.getColSemesterId());
									//
									// Log.d("gCalCourse.getTimeInMillis() >= holidays.getColStartDate()",
									// ""
									// + (gCalCourse.getTimeInMillis() >=
									// holidays.getColStartDate()));
									//
									// Log.d("gCalCourse.getTimeInMillis() < holidays.getColEndDate()",
									// ""
									// + (gCalCourse.getTimeInMillis() <
									// holidays.getColEndDate()));
									
									if (courses.getColSemesterId() == holidays.getColSemesterId()
											&& gCalCourse.getTimeInMillis() >= holidays.getColStartDate()
											&& gCalCourse.getTimeInMillis() <= holidays.getColEndDate()) {
										
										// Set the isHoliday flag
										isHoliday = true;
										
										// Add a new course meeting
										addCourseEntry(false,
												true,
												null);
										
										break;
									}
								}
							} // end checking holiday
							
							if (!(isOverride || isHoliday)) {
								
								// Initializing the entry
								entry.setCourseName(courses.getColName());
								entry.setId(courses.getColId());
								entry.setStartTimeHour(courses.getColStartTimeHour());
								entry.setStartTimeMinute(courses.getColStartTimeMinute());
								entry.setEndTimeHour(courses.getColEndTimeHour());
								entry.setEndTimeMinute(courses.getColEndTimeMinute());
								
								// Add the entry to the batch
								meetingEntries.add(entry);
							}
							
						} // end Check to see if the course meets today
						
					} // end Check to see if today is in the course meeting
						// period
					
				} // end getting the course meetings for today
				
				// Check to see if there are any missing overrides
				if (overrides.contains(0)) {
					for (int j = 0; j < courseTimeOverrides.getCount(); j++) {
						
						// Move the cursor to the correct position
						courseTimeOverrides.moveToPosition(j);
						
						// Get all overrides for today
						
						if (overrides.get(j) == 0
								&& courseTimeOverrides.getColDate() >= gCalCourse.getTimeInMillis()
								&& courseTimeOverrides.getColDate() < nextDay) {
							
							// Initialize the entry
							entry = new CourseMeetingEntry();
							
							// Set the isOverride flag
							isOverride = true;
							
							// Initializing the entry
							entry.setCourseName(courseTimeOverrides.getColCourseName());
							entry.setId(courseTimeOverrides.getColCourseId());
							entry.setStartTimeHour(courseTimeOverrides.getColStartTimeHour());
							entry.setStartTimeMinute(courseTimeOverrides.getColStartTimeMinute());
							entry.setEndTimeHour(courseTimeOverrides.getColEndTimeHour());
							entry.setEndTimeMinute(courseTimeOverrides.getColEndTimeMinute());
							
							// Add the entry to the batch
							meetingEntries.add(entry);
							
							// Unset the position in the override
							// array list
							overrides.set(j,
									1);
						}
					}
				} // end getting all overrides for today
				
				// Sort the batch if needed
				if (meetingEntries.size() > 1) {
					Collections.sort(meetingEntries);
				}
				
				// If there are no upcoming courses for today
				if (isToday
						&& meetingEntries.size() < 1) {
					addCourseEntry(true,
							false,
							null);
				}
				
				// Add all the entries in the batch
				for (int m = 0; m < meetingEntries.size(); m++) {
					addCourseEntry(false,
							false,
							meetingEntries.get(m));
				}
				
			} // end getting all course meetings for this period
			
		}
		
		// Hide all extra rows
		for (int i = currentTblCoursesIndex; i < tblCourses.getChildCount(); i++) {
			tblCourses.getChildAt(i)
					.setVisibility(View.GONE);
		}
		
		// Redraw the screen
		tblCourses.invalidate();
		
	}
	
	// unsetCourseTimeOverrides()
	private void unsetCourseTimeOverrides() {
		overrides = new ArrayList<Integer>();
		for (int i = 0; i < courseTimeOverrides.getCount(); i++) {
			overrides.add(0);
		}
	}
	
	// getMeetingDays()
	private void setMeetingDays() {
		
		// Vars
		meetingDays = new ArrayList<ArrayList<Integer>>();
		ArrayList<Integer> tempArlInt;
		int dayBitField;
		
		// Go through all the courses in the cursor
		for (int i = 0; i < courses.getCount(); i++) {
			
			// Move cursor to correct position
			courses.moveToPosition(i);
			
			// Add the meeting day to the array list
			tempArlInt = new ArrayList<Integer>();
			dayBitField = courses.getColDayBitField();
			if ((dayBitField & DateConstants.SUNDAY_BIT) == DateConstants.SUNDAY_BIT) {
				tempArlInt.add(1);
			}
			if ((dayBitField & DateConstants.MONDAY_BIT) == DateConstants.MONDAY_BIT) {
				tempArlInt.add(2);
			}
			if ((dayBitField & DateConstants.TUESDAY_BIT) == DateConstants.TUESDAY_BIT) {
				tempArlInt.add(3);
			}
			if ((dayBitField & DateConstants.WEDNESDAY_BIT) == DateConstants.WEDNESDAY_BIT) {
				tempArlInt.add(4);
			}
			if ((dayBitField & DateConstants.THURSDAY_BIT) == DateConstants.THURSDAY_BIT) {
				tempArlInt.add(5);
			}
			if ((dayBitField & DateConstants.FRIDAY_BIT) == DateConstants.FRIDAY_BIT) {
				tempArlInt.add(6);
			}
			if ((dayBitField & DateConstants.SATURDAY_BIT) == DateConstants.SATURDAY_BIT) {
				tempArlInt.add(7);
			}
			
			// Adding the array list to the container
			meetingDays.add(tempArlInt);
		}
	}
	
	// getRightBound()
	private long getRightBound() {
		long result = -1;
		GregorianCalendar tempCal = new GregorianCalendar();
		tempCal = new GregorianCalendar(tempCal.get(Calendar.YEAR),
				tempCal.get(Calendar.MONTH),
				tempCal.get(Calendar.DAY_OF_MONTH));
		int dayOfWeek = (tempCal.get(GregorianCalendar.DAY_OF_WEEK) - 1 == 0
				? 7
				: tempCal.get(GregorianCalendar.DAY_OF_WEEK) - 1);
		switch (spinner.getSelectedItemPosition()) {
			case 0:
				return (tempCal.getTimeInMillis() + (7 - dayOfWeek + 1)
						* millisecondsPerDay);
			case 1:
				return (tempCal.getTimeInMillis() + (14 - dayOfWeek + 1)
						* millisecondsPerDay);
			case 2:
				return (tempCal.getTimeInMillis() + (28 - dayOfWeek + 1)
						* millisecondsPerDay);
			case 3:
				ContentValues map = new ContentValues();
				CursorCourse c = db.getCourse(null,
						new String[] { Course.END_DATE },
						false);
				startManagingCursor(c);
				if (c.getCount() > 0) {
					if (c.getColEndDate() != null) {
						return c.getColEndDate() + 1000;
					}
				}
		}
		return result;
	}
	
	// switchMonth()
	private String switchMonth(int theMonth) {
		String result = null;
		switch (theMonth) {
			case 0:
				result = "January";
				break;
			case 1:
				result = "February";
				break;
			case 2:
				result = "March";
				break;
			case 3:
				result = "April";
				break;
			case 4:
				result = "May";
				break;
			case 5:
				result = "June";
				break;
			case 6:
				result = "July";
				break;
			case 7:
				result = "August";
				break;
			case 8:
				result = "September";
				break;
			case 9:
				result = "October";
				break;
			case 10:
				result = "November";
				break;
			case 11:
				result = "December";
				break;
		}
		return result;
	}
	
	// switchDayOfWeek()
	private String switchDayOfWeek(int dayOfWeek) {
		String result = null;
		switch (dayOfWeek) {
			case Calendar.MONDAY:
				result = "Monday";
				break;
			case Calendar.TUESDAY:
				result = "Tuesday";
				break;
			case Calendar.WEDNESDAY:
				result = "Wednesday";
				break;
			case Calendar.THURSDAY:
				result = "Thursday";
				break;
			case Calendar.FRIDAY:
				result = "Friday";
				break;
			case Calendar.SATURDAY:
				result = "Saturday";
				break;
			case Calendar.SUNDAY:
				result = "Sunday";
				break;
		}
		return result;
	}
	
	// isCourseCursorChanged()
	private boolean isCourseCursorChanged() {
		boolean result = false;
		
		CursorCoursesForAgendaView newCourses = db.getCoursesForAgendaView(gCalCourse.getTimeInMillis(),
				getRightBound());
		CursorHoliday newHolidays = db.getHolidaysForAgendaView(gCalCourse.getTimeInMillis(),
				getRightBound());
		CursorCourseTimeOverride newCourseTimeOverrides = db.getCourseTimeOverridesForAgendaView(gCalCourse.getTimeInMillis(),
				getRightBound());
		
		// Compare course cursors
		if (courses.getCount() != newCourses.getCount()) {
			result = true;
		} else {
			for (int i = 0; i < courses.getCount(); i++) {
				
				// Move the cursors to correct position
				courses.moveToPosition(i);
				newCourses.moveToPosition(i);
				
				if (courses.getColName()
						.compareTo(newCourses.getColName()) != 0) {
					result = true;
					break;
				}
				
				if (courses.getColSemesterId() != newCourses.getColSemesterId()) {
					result = true;
					break;
				}
				
				if (courses.getColId() != newCourses.getColId()) {
					result = true;
					break;
				}
				
				if (courses.getColStartTimeHour() != newCourses.getColStartTimeHour()) {
					result = true;
					break;
				}
				
				if (courses.getColStartTimeMinute() != newCourses.getColStartTimeMinute()) {
					result = true;
					break;
				}
				
				if (courses.getColEndTimeHour() != newCourses.getColEndTimeHour()) {
					result = true;
					break;
				}
				
				if (courses.getColEndTimeMinute() != newCourses.getColEndTimeMinute()) {
					result = true;
					break;
				}
				
				if (courses.getColStartDate() != newCourses.getColStartDate()) {
					result = true;
					break;
				}
				
				if (courses.getColEndDate() != newCourses.getColEndDate()) {
					result = true;
					break;
				}
			}
		}
		
		// Compare holiday cursors
		if (newHolidays.getCount() != holidays.getCount()) {
			result = true;
		} else {
			for (int i = 0; i < holidays.getCount(); i++) {
				
				// Move the cursors to correct position
				holidays.moveToPosition(i);
				newHolidays.moveToPosition(i);
				
				if (newHolidays.getColName()
						.compareTo(holidays.getColName()) != 0) {
					result = true;
					break;
				}
				
				if (newHolidays.getColSemesterId() != holidays.getColSemesterId()) {
					result = true;
					break;
				}
				
				if (newHolidays.getColStartDate() != holidays.getColStartDate()) {
					result = true;
					break;
				}
				
				if (newHolidays.getColEndDate() != holidays.getColEndDate()) {
					result = true;
					break;
				}
			}
		}
		
		// compare override cursors
		if (newCourseTimeOverrides.getCount() != courseTimeOverrides.getCount()) {
			result = true;
		} else {
			for (int i = 0; i < courseTimeOverrides.getCount(); i++) {
				
				// Move the cursors to correct position
				courseTimeOverrides.moveToPosition(i);
				newCourseTimeOverrides.moveToPosition(i);
				
				if (courseTimeOverrides.getColId() != newCourseTimeOverrides.getColId()) {
					result = true;
					break;
				}
				
				if (courseTimeOverrides.getColStartTimeHour() != newCourseTimeOverrides.getColStartTimeHour()) {
					result = true;
					break;
				}
				
				if (courseTimeOverrides.getColStartTimeMinute() != newCourseTimeOverrides.getColStartTimeMinute()) {
					result = true;
					break;
				}
				
				if (courseTimeOverrides.getColEndTimeHour() != newCourseTimeOverrides.getColEndTimeHour()) {
					result = true;
					break;
				}
				
				if (courseTimeOverrides.getColEndTimeMinute() != newCourseTimeOverrides.getColEndTimeMinute()) {
					result = true;
					break;
				}
				
				if (courseTimeOverrides.getColDate() != newCourseTimeOverrides.getColDate()) {
					result = true;
					break;
				}
				
			}
			
		}
		
		newCourses.close();
		newHolidays.close();
		newCourseTimeOverrides.close();
		return result;
	}
	
	// isTaskCursorChanged()
	private boolean isTaskCursorChanged() {
		
		boolean result = false;
		
		CursorTaskForAgendaView newTasks = db.getTasksForAgendaView(gCalTask.getTimeInMillis());
		
		if (newTasks.getCount() != tasks.getCount()) {
			result = true;
		} else {
			for (int i = 0; i < newTasks.getCount(); i++) {
				
				newTasks.moveToPosition(i);
				tasks.moveToPosition(i);
				
				if (newTasks.getColCourseName()
						.compareTo(tasks.getColCourseName()) != 0) {
					result = true;
					break;
				}
				
				if (newTasks.getColId() != tasks.getColId()) {
					result = true;
					break;
				}
				
				if (newTasks.getColName()
						.compareTo(tasks.getColName()) != 0) {
					result = true;
					break;
				}
				
				if (newTasks.getColIsCompleted() != tasks.getColIsCompleted()) {
					result = true;
					break;
				}
				
				if (newTasks.getColDateDue()
						.longValue() != tasks.getColDateDue()
						.longValue()) {
					result = true;
					break;
				}
			}
		}
		
		newTasks.close();
		return result;
	}
	
}
